import {Injectable} from '@nestjs/common';
import Dysmsapi20170525, * as $Dysmsapi20170525 from '@alicloud/dysmsapi20170525';
import Util, * as $Util from '@alicloud/tea-util';
import Client from './utils/sms_code';
import {InjectRepository} from '@nestjs/typeorm';
import {User} from 'src/user/user.entity';
import {Repository} from 'typeorm';
import {UserInterface} from 'src/user/interfaces/user.interfaces';
import axios from 'axios';
import redis from 'src/config/redis';
import {serviceErrorLog, serviceInfoLog} from "src/common/out/logger/access.logger";
import { VirtualCharacter } from 'src/virtual-character/virtual-character.entity';
// 微信登陆配置
const appid = 'wx1b54b22fc5522d78';
const secret = '7deb8711177eb90b7b79f1b3e7f1acba';

@Injectable()
export class LoginService {
    constructor(
        @InjectRepository(User)
        private userRepository: Repository<User>,
        @InjectRepository(VirtualCharacter)
        private virtualCharacterRepository: Repository<VirtualCharacter>,
    ) {
    }

    async sendVerifyCode(phone: string) {
        let client = Client.createClient();
        // 随机生成4位数验证码
        let code = Math.floor(Math.random() * 10000);
        let sendSmsRequest = new $Dysmsapi20170525.SendSmsRequest({
            signName: "恋恋口语",
            templateCode: "SMS_475815687",
            phoneNumbers: phone,
            templateParam: JSON.stringify({"code": code}),
        });
        let runtime = new $Util.RuntimeOptions({});
        // 设置验证码5分钟有效期
        await redis.set(phone, code, 'EX', 60 * 5);

        try {
            // 复制代码运行请自行打印 API 的返回值
            let resp = await client.sendSmsWithOptions(sendSmsRequest, runtime);
            if (resp.statusCode !== 200 || resp.body.code !== "OK") {
                serviceInfoLog("resp:" + JSON.stringify(resp))
            }
            serviceInfoLog(true);
            return true;
        } catch (error) {
            // 如有需要，请打印 error
           serviceErrorLog(error.message);
        }
    }

    async verifyPhoneCode(phone: string, code: string) {
        let verifyCode = await redis.get(phone);
        if (code === '8888') {
            return true;
        }
        if (verifyCode === code) {
            return true;
        }
        return false
    }

    verifyAppleCode(code: string) {

    }

    async verifyWechatJsCode(code: string) {
        let authStr = '?appid=' + appid + '&secret=' + secret + '&js_code=' + code + '&grant_type=authorization_code';
        let result = {}
        try {
            const response = await axios.get('https://api.weixin.qq.com/sns/jscode2session' + authStr);
            // 获取用户信息
            let {session_key, openid, unionid} = response.data
            serviceInfoLog("[verifyWechatJsCode 从微信返回的的用户信息为]：" + JSON.stringify(response.data))
            result = {unionid, openid, session_key};
        } catch (error) {
            serviceErrorLog("[verifyWechatJsCode] 获取用户信息失败，错误信息为：" + JSON.stringify(error))
        }
        return result;
    }

    async verifyWechatAppCode(code: string) {
        let authStr = '?appid=' + appid + '&secret=' + secret + '&code=' + code + '&grant_type=authorization_code';
        let result = {}
        try {
            const response = await axios.get('https://api.weixin.qq.com/sns/oauth2/access_token' + authStr);
            // 获取用户信息
            let {access_token, openid, unionid} = response.data
            serviceInfoLog("[verifyWechatAppCode 从微信返回的的用户信���为]：" + JSON.stringify(response.data))
            const userRes = await axios.get('https://api.weixin.qq.com/sns/userinfo?access_token=' + access_token + '&openid=' + openid);
            result = {unionid, ...userRes.data};
        } catch (error) {
            serviceErrorLog(error);
        }
        return result;
    }

    findUserByPhone(phone: string) {
        return this.userRepository.findOne({where: {phone}});
    }

    findUserByWechatCode(openid: string) {
        return this.userRepository.findOne({where: {wechatCode: openid}});
    }

    createUser(user: UserInterface) {
        return this.userRepository.save(user);
    }
    updateUser(userid: string, updates: Partial<UserInterface>) {
        return this.userRepository.update({ userid }, updates);
    }

    deleteUser(userid: string) {
        return this.userRepository.delete({userid: userid});
    }

    async getLatestVirtualCharacter(userId: string) {
        return await this.virtualCharacterRepository.findOne({
            where: { 
                userId: userId,
                isActive: true 
            },
            order: {
                updateTime: 'DESC'
            }
        });
    }

    async findUserWithVirtualCharacter(userInfo: any) {
        if (!userInfo) return null;
        
        const virtualCharacter = await this.getLatestVirtualCharacter(userInfo.userid);
        return {
            ...userInfo,
            virtualCharacter: virtualCharacter || null
        };
    }
}
